Windows 11 端末のファイルを s3 sync コマンドで S3 バケットに同期する

Windows 11 端末のファイルを s3 sync コマンドで S3 バケットに同期する

Windows 11 端末のファイルを s3 sync コマンドで S3 バケットに同期してみました。
Clock Icon2025.01.10

コーヒーが好きな emi です。

Windows クライアント端末(Windows 10 や Windows 11 など)内のテキストデータを AWS に連携する方法を検討する中で aws s3 sync コマンドを使った方法を検証しました。
検証手順を共有します。

イメージ図

特定の S3 バケットへの書き込み権限のみを持った IAM ユーザーのアクセスキーを Windows 端末に配置し、AWS CLI コマンド aws s3 sync で S3 バケットにファイルを同期します。
windows-11-s3-sync_12

Windows 11 のバージョン確認

Windoes マーク + R で「ファイル名を指定して実行」を開き、winver と有力して OK をクリックします。
windows-11-s3-sync_1

Windows 11 のバージョンは以下でした。
windows-11-s3-sync_2

IAM ユーザーのアクセスキーを Windows 11 端末に配置する

S3 バケットへのファイル同期用の IAM ユーザーのアクセスキーを払い出して設定します。

AWS マネジメントコンソールにアクセスする際に使用している IAM ユーザーではなく、特定の S3 バケットへファイルを書き込む権限のみを付与した IAM ユーザーを別途払い出します。(最小権限の法則

特定の S3 バケットへの書き込み許可のみ与えたいので、S3 バケットはあらかじめ作成してバケット名をメモしておいてください。

まずは IAM ユーザーを作成します。今回は「windows-sync-user」というユーザーを作成しました。
windows-11-s3-sync_3

作成した IAM ユーザーには以下の IAM ポリシーを付与しました。
※このポリシーは不足しているためブログの後半で修正します。

IAM ポリシー「put_windows-sync-emikitani-20250106」
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::windows-sync-emikitani-20250106/${aws:username}/*"
        }
    ]
}

windows-sync-emikitani-20250106 の部分はご自身が作成した S3 バケット名に編集してください。

次に、作成した IAM ユーザーのアクセスキーを発行します。ユースケースは「コマンドラインインターフェイス(CLI)」にチェックし、画面下部の確認にチェックして「次へ」をクリックします。
windows-11-s3-sync_4

説明を追加してアクセスキーを発行します。
windows-11-s3-sync_5

アクセスキーが発行できたら、忘れずに .csv ファイルをダウンロードしておきます。
windows-11-s3-sync_6

データ同期前の S3 バケット

データ同期前の S3 バケットは以下のように空っぽです。バケットポリシーは設定していません。
windows-11-s3-sync_7

同期するサンプルファイルを作成

同期するサンプルファイルを手元の Windows 11 端末で作成します。
今回は手作業でちくちく作成しました。作成したファイル一覧を tree コマンドで表示すると以下です。

tree "C:\work\windows-sync-emikitani-20250106" /f

/f オプションで各フォルダ内のファイルも一覧に表示します。

▼実行結果

PS C:\Users\kitani.emi> tree "C:\work\windows-sync-emikitani-20250106" /f
フォルダー パスの一覧:  ボリューム Local Disk
ボリューム シリアル番号は 30C9-180E です
C:\WORK\WINDOWS-SYNC-EMIKITANI-20250106
└─2025
    └─01
        ├─01
        │      20250101.txt
        │
        ├─02
        │      20250102.txt
        │
        ├─03
        │      20250103.txt
        │
        ├─04
        │      20250104.txt
        │
        ├─05
        │      20250105.txt
        │
        └─06
                20250106.txt

PS C:\Users\kitani.emi>

変数設定

PowerShell で順番にコマンドを実行していきます。

  • S3 バケットを指定
$s3bucket = "s3://windows-sync-emikitani-20250106"

▼実行結果

PS C:\Users\kitani.emi> $s3bucket = "s3://windows-sync-emikitani-20250106"
PS C:\Users\kitani.emi>
  • $s3bucket 変数の確認
Write-Output $s3bucket

▼実行結果

PS C:\Users\kitani.emi> Write-Output $s3bucket
s3://windows-sync-emikitani-20250106
PS C:\Users\kitani.emi>
  • S3 バケット配下のプレフィックスを指定
$username = "windows-sync-user"

▼実行結果

PS C:\Users\kitani.emi> $username = "windows-sync-user"
PS C:\Users\kitani.emi>
  • $username 変数の確認
Write-Output $username   

▼実行結果

PS C:\Users\kitani.emi> Write-Output $username         
windows-sync-user
PS C:\Users\kitani.emi> 
  • Windows 端末内のローカルフォルダを指定
$localfolder = "C:\work\windows-sync-emikitani-20250106"

▼実行結果

PS C:\Users\kitani.emi> $localfolder = "C:\work\windows-sync-emikitani-20250106"
PS C:\Users\kitani.emi>
  • $localfolder 変数の確認
Write-Output $localfolder

▼実行結果

PS C:\Users\kitani.emi> Write-Output $localfolder
C:\work\windows-sync-emikitani-20250106
PS C:\Users\kitani.emi>
  • プロファイルを設定
$iamprofile = "windows-sync-user"

▼実行結果

PS C:\Users\kitani.emi> $iamprofile = "windows-sync-user"
PS C:\Users\kitani.emi>
  • $iamprofile 変数の確認
Write-Output $iamprofile
PS C:\Users\kitani.emi> Write-Output $iamprofile
windows-sync-user
PS C:\Users\kitani.emi>

各種変数が設定できました。

S3 バケットへのデータ同期

では s3 sync コマンドでローカルフォルダとs3バケットを同期します。

aws s3 sync $localfolder $s3bucket/$username --profile $iamprofile

▼実行結果

PS C:\Users\kitani.emi> aws s3 sync $localfolder $s3bucket/$username --profile $iamprofile
fatal error: An error occurred (AccessDenied) when calling the ListObjectsV2 operation: User: arn:aws:iam::222222222222:user/windows-sync-user is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::windows-sync-emikitani-20250106" because no identity-based policy allows the s3:ListBucket action
PS C:\Users\kitani.emi> 

s3:ListBucket 権限が不足しているというエラーになりました。

aws s3 sync コマンドはローカルフォルダと S3 バケットの状態を比較して差分を同期するため、s3:ListBucket 権限が必要なのでした。

書き込みだけの場合の解決策

もしローカルのデータを単純に S3 バケットに書き込むだけで、バケット内の既存オブジェクトと比較する必要がない場合は s3:ListBucket 権限不要で aws s3 cp コマンドが使用できます。

aws s3 cp の例

aws s3 cp $localfolder $s3bucket --recursive --profile $iamprofile

--recursive オプションを指定するとプレフィックス配下のすべてのオブジェクトに対してコマンドが実行されます。(ローカルフォルダ内のすべてのファイルとサブフォルダを再帰的にアップロードする)

  • 注意点
    • 差分を比較せずすべてのファイルを再アップロードするため、ファイルの削除や更新が必要な場合は、自動では行えません。
    • 差分の同期が必要なら aws s3 sync を使用し、s3:ListBucket 権限を付与するのが最適です。

どちらの方法を選択するかは、要件に応じて検討してください。

アクセスキーを発行した「windows-sync-user」ユーザーに付与した IAM ポリシーを以下のように変更します。

IAM ポリシー「put_windows-sync-emikitani-20250106」変更後
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::windows-sync-emikitani-20250106"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::windows-sync-emikitani-20250106/${aws:username}/*"
        }
    ]
}
余談:うまくいかなかったポリシー

以下のようにユーザー名のパス配下に対する s3:ListBucket 権限ではダメでした。
S3 バケット全体をリストできないといけないです。

うまくいかなかったポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"s3:ListBucket"
			],
			"Resource": "arn:aws:s3:::windows-sync-emikitani-20250106/${aws:username}"
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::windows-sync-emikitani-20250106/${aws:username}/*"
		}
	]
}

では、再度同期を実行します。

▼実行結果

PS C:\Users\kitani.emi> aws s3 sync $localfolder $s3bucket/$username --profile $iamprofile
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\02\20250102.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/02/20250102.txt
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\04\20250104.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/04/20250104.txt
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\01\20250101.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/01/20250101.txt
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\05\20250105.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/05/20250105.txt
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\06\20250106.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/06/20250106.txt
upload: ..\..\work\windows-sync-emikitani-20250106\2025\01\03\20250103.txt to s3://windows-sync-emikitani-20250106/windows-sync-user/2025/01/03/20250103.txt
PS C:\Users\kitani.emi> 

エラーなくコマンドが実行されました!

S3 バケットを見ると、ユーザー名「windows-sync-user」のプレフィックス配下にデータが無事同期されています。
windows-11-s3-sync_8

windows-11-s3-sync_9

ファイルを開いてみます。
windows-11-s3-sync_10

ファイルの内容も同期されています。
windows-11-s3-sync_11

ちなみに S3 バケット側のプレフィックスにユーザー名を含めた理由は、Windows 端末が増えた場合に端末ごとのデータをプレフィックスごとに分けてみたかったからです。

windows-11-s3-sync_14

▼ S3 プレフィックスのイメージ
windows-11-s3-sync_13

要件に応じてプレフィックスの設計を行ってください。

終わりに

今回実行したコマンドをスクリプトなどにまとめてタスクスケジューラーで定期実行し定期的にファイルを S3 バケットに収集する仕組みもできそうです。

質問やご要望については画面下部のお問い合わせ「DevelopersIO について」からご連絡ください。記事に関してお問い合わせいただけます。

参考

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html#cli-aws-s3

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.